
import os

import json
import subprocess

def probe_file(p):
    args = [
        'ffprobe',
        '-loglevel', 'error',
        '-show_streams', '-show_format',
        '-print_format', 'json',
        '-i', p
    ]

    p = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    if p.returncode != 0:
        raise RuntimeError(p.stderr.replace('\n', ' '))

    data = json.loads(p.stdout)
    return data

def extract_stream_props(probe):
    dur = int(round(float(probe['format']['duration'])))
    br = int(probe['format']['bit_rate'])

    title = None
    if 'tags' in probe['format']:
        tags = probe['format']['tags']
        if 'title' in tags:
            title = tags['title']

    for s in probe['streams']:
        if s['codec_type'] == 'video':
            return {
                'title': title,
                'res_w': s['width'],
                'res_h': s['height'],
                'duration_sec': dur,
                'bitrate_bps': br,
                'codec': s['codec_name'],
            }

def reencode(src, dest, target_br_kbps, preset='veryfast', maxheight=1080, dryrun=False):
    baseargs = [
        'ffmpeg',
        '-i', src,
        '-c:v', 'libx265',
        '-preset', preset,
        '-vf', 'scale=-1:\'min(%s,ih)\'' % maxheight,
        '-b:v', '%sk' % target_br_kbps,
        '-y',
    ]

    p1args = baseargs + [
        '-x265-params', 'pass=1',
        '-an',
        '-f', 'null',
        '/dev/null'
    ]

    p2args = baseargs + [
        '-map', '0',
        '-x265-params', 'pass=2',
        '-c:a', 'aac',
        '-b:a', '400k',
        '-c:s', 'copy',
        #'-c:d', 'copy',
        #'-c:t', 'copy',
        dest
    ]

    print('PASS1', ' '.join(p1args))
    if not dryrun:
        res1 = subprocess.run(p1args)
        res1.check_returncode()

    print('PASS2', ' '.join(p2args))
    if not dryrun:
        res2 = subprocess.run(p2args)
        res2.check_returncode()

    # Do cleanup
    if not dryrun:
        destdir = os.path.dirname(os.path.realpath(dest))
        for f in os.listdir(destdir):
            if f.startswith('x265_2pass.log'):
                os.unlink(os.path.join(destdir, f))
